#include <iup.h>
#include <iuptree.h>
#include <iupgl.h>
#include <iupim.h>



#include <stdarg.h>
#include <stdlib.h>


#ifdef WIN32
#define EXPORT(T) extern "C" __declspec(dllexport) T
#elif defined LIN26
#define EXPORT(T) extern "C"  T
#endif

//todo: move above define to a common header
//todo: change cpp files to be c file (and remove extern "C" from export defines)

//declare a dummy main function to satisfy iup defines
int main(int ,char** ) {return 0;}


EXPORT(Ihandle*) FileDlg(void) {return IupFileDlg();}
EXPORT(Ihandle*) MessageDlg(void) {return IupMessageDlg();}
EXPORT(Ihandle*) ColorDlg(void) {return IupColorDlg();}
EXPORT(Ihandle*) FontDlg(void) {return IupFontDlg();}


EXPORT(int) GetFile(char* arg) {return IupGetFile(arg);}
//todo: Messagef how to handle varargs?
EXPORT(void) Message(const char* title,const char* msg) {IupMessage(title,msg);}
EXPORT(int) Alarm(const char *title, const char *msg, const char *b1, const char *b2, const char *b3) {return IupAlarm(title,msg,b1,b2,b3);}
//int  IupScanf(const char *format, ...); //todo: how to handle varargs?
EXPORT(int) ListDialog(int type, const char *title, int size, const char** list, int op, int max_col, int max_lin, int* marks) {return IupListDialog(type,title,size,list,op,max_col,max_lin,marks);}
EXPORT(int) GetText(const char* title,char* text) {return IupGetText(title,text);}
EXPORT(int) GetColor(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b) {return IupGetColor(x,y,r,g,b);}
//todo: how to handle varargs?
//EXPORT(int) IupGetParam(const char* title, Iparamcb action, void* user_data, const char* format,...);
EXPORT(int) GetParamv(const char* title, Iparamcb action, void* user_data, const char* format, int param_count, int param_extra, void** param_data) {return IupGetParamv(title,action,user_data,format,param_count,param_extra,param_data);}
EXPORT(int) Open(int* argc,char*** argv) {return IupOpen(argc,argv);}
EXPORT(void) Close() {IupClose();}
//EXPORT(void) ImageLibOpen() {IupImageLibOpen();} //todo: needs imagelib
EXPORT(int) MainLoop() {return IupMainLoop();}
EXPORT(int) LoopStep() {return IupLoopStep();}
EXPORT(int) MainLoopLevel() {return IupMainLoopLevel();}
EXPORT(void) Flush() {IupFlush();}
EXPORT(void) ExitLoop() {IupExitLoop();}
EXPORT(void) Update (Ihandle* ih) {IupUpdate(ih);}
EXPORT(void) UpdateChildren(Ihandle* ih) {IupUpdateChildren(ih);}
EXPORT(void) Redraw(Ihandle* ih, int children) {IupRedraw(ih,children);}
EXPORT(void) Refresh(Ihandle* ih) {IupRefresh(ih);}
EXPORT(char*) MapFont(const char *iupfont) {return IupMapFont(iupfont);}
EXPORT(char*) UnMapFont(const char *driverfont) {return IupUnMapFont(driverfont);}
EXPORT(int) Help(const char* url) {return IupHelp(url);}
EXPORT(char*) Load(const char *filename) {return IupLoad(filename);}
EXPORT(char*) Version() {return IupVersion();}
EXPORT(char*) VersionDate() {return IupVersionDate();}
EXPORT(int) VersionNumber() {return IupVersionNumber();}
EXPORT(void) SetLanguage(const char *lng) {IupSetLanguage(lng);}
EXPORT(char*) GetLanguage() {return IupGetLanguage();}
EXPORT(void) Destroy(Ihandle* ih) {IupDestroy(ih);}
EXPORT(void) Detach(Ihandle* ih) {IupDetach(ih);}
EXPORT(Ihandle*) Append(Ihandle* ih, Ihandle* child) {return IupAppend(ih,child);}
EXPORT(Ihandle*) Insert(Ihandle* ih, Ihandle* ref_child, Ihandle* child) {return IupInsert(ih,ref_child,child);}

EXPORT(Ihandle*) GetChild(Ihandle* ih, int pos) {return IupGetChild(ih,pos);}
EXPORT(int)       GetChildPos  (Ihandle* ih, Ihandle* child) {return IupGetChildPos(ih,child);}
EXPORT(int)       GetChildCount(Ihandle* ih) {return IupGetChildCount(ih);}
EXPORT(Ihandle*)  GetNextChild (Ihandle* ih, Ihandle* child) {return IupGetNextChild(ih,child);}
EXPORT(Ihandle*)  GetBrother   (Ihandle* ih) {return IupGetBrother(ih);}
EXPORT(Ihandle*)  GetParent    (Ihandle* ih) {return IupGetParent(ih);}
EXPORT(Ihandle*)  GetDialog    (Ihandle* ih) {return IupGetDialog(ih);}
EXPORT(Ihandle*)  GetDialogChild(Ihandle* ih, const char* name) {return IupGetDialogChild(ih,name);}
EXPORT(int)       Reparent     (Ihandle* ih, Ihandle* new_parent) {return IupReparent(ih,new_parent);}

EXPORT(int)       Popup         (Ihandle* ih, int x, int y) {return IupPopup(ih,x,y);}
EXPORT(int)       Show          (Ihandle* ih) {return IupShow(ih);}
EXPORT(int)       ShowXY        (Ihandle* ih, int x, int y) {return IupShowXY(ih,x,y);}
EXPORT(int)       Hide          (Ihandle* ih) {return IupHide(ih);}
EXPORT(int)       Map           (Ihandle* ih) {return IupMap(ih);}
EXPORT(void)      Unmap         (Ihandle *ih) {IupUnmap(ih);}

////note: do NOT use SetAttribute to set strings, only pointers....
EXPORT(void) SetAttribute(Ihandle* ih,const char* name,const char* value) {IupSetAttribute(ih,name,value);}
EXPORT(void) StoreAttribute(Ihandle* ih,const char* name,const char* value) {IupStoreAttribute(ih,name,value);}
EXPORT(Ihandle*) SetAttributes (Ihandle* ih, const char *str) {return IupSetAttributes(ih,str);}
EXPORT(char*) GetAttribute  (Ihandle* ih, const char* name) {return IupGetAttribute(ih,name);}
EXPORT(char*) GetAttributes(Ihandle* ih) {return IupGetAttributes(ih);}
EXPORT(int) GetInt(Ihandle* ih, const char* name) {return IupGetInt(ih,name);}
EXPORT(int) GetInt2(Ihandle* ih, const char* name) {return IupGetInt2(ih,name);}
EXPORT(int) GetIntInt(Ihandle* ih, const char* name,int* i1,int* i2) {return IupGetIntInt(ih,name,i1,i2);}
EXPORT(float) GetFloat(Ihandle* ih, const char* name) {return IupGetFloat(ih,name);}

//todo: how to handle varargs
//void      IupSetfAttribute (Ihandle* ih, const char* name, const char* format, ...);

EXPORT(int) GetAllAttributes(Ihandle* ih, char** names, int n) {return IupGetAllAttributes(ih,names,n);}
//todo: this function is probaly not usable, should we have it (stores char* directly)?
//EXPORT(void) SetGlobal(const char* name, const char* value) {IupSetGlobal(name,value);}
EXPORT(void) StoreGlobal(const char* name, const char* value) {IupStoreGlobal(name,value);}
EXPORT(char*) GetGlobal(const char* name) {return IupGetGlobal(name);}
EXPORT(Ihandle*) SetFocus(Ihandle* ih) {return IupSetFocus(ih);}
EXPORT(Ihandle*) GetFocus(void) {return IupGetFocus();}
EXPORT(Ihandle*) PreviousField (Ihandle* ih) {return IupPreviousField(ih);}
EXPORT(Ihandle*) NextField(Ihandle* ih) {return IupNextField(ih);}
EXPORT(Icallback) GetCallback(Ihandle*ih,const char* name) {return IupGetCallback(ih,name);}
EXPORT(Icallback) SetCallback(Ihandle* ih, const char *name, Icallback func) {return IupSetCallback(ih,name,func);}

//todo: how to handle varargs
//Ihandle*  IupSetCallbacks(Ihandle* ih, const char *name, Icallback func, ...);

EXPORT(Icallback) GetFunction(const char *name) {return IupGetFunction(name);}
EXPORT(Icallback) SetFunction(const char *name, Icallback func) {return IupSetFunction(name,func);}
EXPORT(const char*) GetActionName (void) {return IupGetActionName();}
EXPORT(Ihandle*) GetHandle(const char *name) {return IupGetHandle(name);}
EXPORT(Ihandle*) SetHandle(const char *name,Ihandle* ih) {return IupSetHandle(name,ih);}
EXPORT(int) GetAllNames(char** names, int n) {return IupGetAllNames(names,n);}
EXPORT(int) GetAllDialogs(char** names, int n) {return IupGetAllDialogs(names,n);}
EXPORT(char*) GetName(Ihandle* ih) {return IupGetName(ih);}
EXPORT(void) SetAttributeHandle(Ihandle* ih, const char* name, Ihandle* ih_named) {IupSetAttributeHandle(ih,name,ih_named);}
EXPORT(char*) GetClassName(Ihandle* ih) {return IupGetClassName(ih);}
EXPORT(char*) GetClassType(Ihandle* ih) {return IupGetClassType(ih);}
EXPORT(int) GetClassAttributes(const char* classname, char** names, int n) {return IupGetClassAttributes(classname,names,n);}
EXPORT(void) SaveClassAttributes(Ihandle* ih) {IupSaveClassAttributes(ih);}
EXPORT(void) SetClassDefaultAttribute(const char* classname, const char *name, const char* value) {IupSetClassDefaultAttribute(classname,name,value);}
EXPORT(Ihandle*) Create(const char *classname) {return IupCreate(classname);}
EXPORT(Ihandle*) Createv(const char *classname, void* *params) {return IupCreatev(classname,params);}
//Ihandle*  IupCreatep(const char *classname, void *first, ...); //todo: how to handle varargs
EXPORT(Ihandle*) Fill(void) {return IupFill();}
EXPORT(Ihandle*) Radio(Ihandle* child) {return IupRadio(child);}
//EXPORT(Ihandle*) Vbox(Ihandle* child, ...);//todo: how to handle varargs
EXPORT(Ihandle*) Vboxv(Ihandle* *children) {return IupVboxv(children);}
//Ihandle*  IupZbox       (Ihandle* child, ...); //todo: how to handle varargs
EXPORT(Ihandle*) Zboxv(Ihandle* *children) {return IupZboxv(children);}
//Ihandle*  IupHbox       (Ihandle* child,...); //todo: how to handle varargs
EXPORT(Ihandle*) Hboxv(Ihandle* *children) {return IupHboxv(children);}
//Ihandle*  IupNormalizer (Ihandle* ih_first, ...); //todo: how to handle varargs
EXPORT(Ihandle*) Normalizerv(Ihandle* *ih_list) {return IupNormalizerv(ih_list);}
//Ihandle*  IupCbox       (Ihandle* child, ...); //todo: how to handle varargs
EXPORT(Ihandle*) Cboxv(Ihandle* *children) {return IupCboxv(children);}
EXPORT(Ihandle*) Sbox(Ihandle *child) {return IupSbox(child);}
EXPORT(Ihandle*) Frame(Ihandle* child) {return IupFrame(child);}
EXPORT(Ihandle*) Image(int width, int height, const unsigned char *pixmap) {return IupImage(width,height,pixmap);}
EXPORT(Ihandle*) ImageRGB(int width, int height, const unsigned char *pixmap) {return IupImageRGBA(width,height,pixmap);}
EXPORT(Ihandle*) ImageRGBA(int width, int height, const unsigned char *pixmap) {return IupImageRGBA(width,height,pixmap);}
EXPORT(Ihandle*) Item(const char* title, const char* action) {return IupItem(title,action);}
EXPORT(Ihandle*) Submenu(const char* title, Ihandle* child) {return IupSubmenu(title,child);}
EXPORT(Ihandle*) Separator(void) {return IupSeparator();}
//Ihandle*  IupMenu       (Ihandle* child,...);//todo: how to handle varargs
EXPORT(Ihandle*) Menuv(Ihandle* *children) {return IupMenuv(children);}
EXPORT(Ihandle*) Button(const char* title, const char* action) {return IupButton(title,action);}
EXPORT(Ihandle*) Canvas(const char* action) {return IupCanvas(action);}
EXPORT(Ihandle*) Dialog(Ihandle* child) {return IupDialog(child);}
EXPORT(Ihandle*) User(void) {return IupUser();}
EXPORT(Ihandle*) Label(const char* title) {return IupLabel(title);}
EXPORT(Ihandle*) List(const char* action) {return IupList(action);}
EXPORT(Ihandle*) Text(const char* action) {return IupText(action);}

EXPORT(Ihandle*)  MultiLine  (const char* action) {return IupMultiLine(action);}
EXPORT(Ihandle*)  Toggle     (const char* title, const char* action) {return IupToggle(title,action);}
EXPORT(Ihandle*)  Timer      (void) {return IupTimer();}
EXPORT(Ihandle*)  ProgressBar(void) {return IupProgressBar();}
EXPORT(Ihandle*)  Val        (const char *type) {return IupVal(type);}
//EXPORT(Ihandle*  IupTabs       (Ihandle* child, ...); //todo: how to handle varargs
EXPORT(Ihandle*)  Tabsv      (Ihandle* *children) {return IupTabsv(children);}
EXPORT(Ihandle*)  Tree       (void) {return IupTree();}
EXPORT(Ihandle*)  Spin       (void) {return IupSpin();}
EXPORT(Ihandle*)  Spinbox    (Ihandle* child) {return IupSpinbox(child);}

////////////////////////////////////////
// Text utilities
////////////////////////////////////////
EXPORT(void)  TextConvertLinColToPos(Ihandle* ih, int lin, int col, int *pos) {IupTextConvertLinColToPos(ih, lin, col, pos);}
EXPORT(void)  TextConvertPosToLinCol(Ihandle* ih, int pos, int *lin, int *col) {IupTextConvertPosToLinCol(ih, pos, lin, col);}
EXPORT(int)   ConvertXYToPos(Ihandle* ih, int x, int y) {return IupConvertXYToPos(ih,x,y);}  /* works also for list and tree */


////////////////////////////////////////
// Tree functions
////////////////////////////////////////
EXPORT(int)   TreeSetUserId(Ihandle* ih, int id, void* userid) {return IupTreeSetUserId(ih,id,userid);}
EXPORT(void*) TreeGetUserId(Ihandle* ih, int id) {return IupTreeGetUserId(ih,id);}
EXPORT(int)   TreeGetId(Ihandle* ih, void *userid) {return IupTreeGetId(ih,userid);}

EXPORT(void)  TreeStoreAttribute(Ihandle* ih, const char* name, int id, char* value) {IupTreeStoreAttribute(ih,name,id,value);}
EXPORT(char*) TreeGetAttribute  (Ihandle* ih, const char* name, int id) {return IupTreeGetAttribute(ih,name,id);}
EXPORT(int)   TreeGetInt        (Ihandle* ih, const char* name, int id) {return IupTreeGetInt(ih,name,id);}
EXPORT(float) TreeGetFloat      (Ihandle* ih, const char* name, int id) {return IupTreeGetFloat(ih,name,id);}

////////////////////////////////////////
// Open GL functionality
////////////////////////////////////////
EXPORT(void) GLCanvasOpen() {IupGLCanvasOpen();}
EXPORT(Ihandle*) GLCanvas(const char* action) {return IupGLCanvas(action);}
EXPORT(void) GLMakeCurrent(Ihandle* ih) {IupGLMakeCurrent(ih);}
EXPORT(int) GLIsCurrent(Ihandle* ih) {return IupGLIsCurrent(ih);}
EXPORT(void) GLSwapBuffers(Ihandle* ih) {return IupGLSwapBuffers(ih);}
EXPORT(void) GLPalette(Ihandle* ih,int index,float r,float g,float b) {IupGLPalette(ih,index,r,g,b);}


////////////////////////////////////////
// Image lib.
////////////////////////////////////////
EXPORT(void) ImageLibOpen() {return IupImageLibOpen();}


////////////////////////////////////////
// IM Library link
////////////////////////////////////////
EXPORT(Ihandle*) LoadImage(const char* file_name) {return IupLoadImage(file_name);}
EXPORT(int) SaveImage(Ihandle* ih,char* file_name,char* format) {return IupSaveImage( ih,file_name,format);}

